package com.example.springbatch_step_flow;

import com.example.springbatch_step_condition2.MyStatusDecider;
import com.sun.org.apache.regexp.internal.RE;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.job.builder.FlowBuilder;
import org.springframework.batch.core.job.flow.Flow;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

/***
 *
 */
@SpringBootApplication
@EnableBatchProcessing //启用springbatch框架 需要的注解
public class SpringBatchApplication9 {

    // job调度器
    @Autowired
    private JobLauncher jobLauncher;

    // job构建工厂
    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    // step步骤构建工厂
    @Autowired
    private StepBuilderFactory stepBuilderFactory;




    @Bean
    public Tasklet taskletA() {
        return (stepContribution, chunkContext) -> {

            System.out.println("------ A Tasklet ------");

            // 返回执行任务完成
            return RepeatStatus.FINISHED;
        };
    }

    @Bean
    public Tasklet taskletB() {
        return (stepContribution, chunkContext) -> {
            System.out.println("------ B Tasklet ------");

            // 返回执行任务完成
            return RepeatStatus.FINISHED;
        };
    }


    @Bean
    public Tasklet taskletB1() {
        return (stepContribution, chunkContext) -> {
            System.out.println("------ B1 Tasklet ------");

            // 返回执行任务完成
            return RepeatStatus.FINISHED;
        };
    }

    @Bean
    public Tasklet taskletB2() {
        return (stepContribution, chunkContext) -> {
            System.out.println("------ B2 Tasklet ------");

            // 返回执行任务完成
            return RepeatStatus.FINISHED;
        };
    }

    @Bean
    public Tasklet taskletB3() {
        return (stepContribution, chunkContext) -> {
            System.out.println("------ B3 Tasklet ------");

            // 返回执行任务完成
            return RepeatStatus.FINISHED;
        };
    }


    @Bean
    public Tasklet taskletC() {
        return (stepContribution, chunkContext) -> {
            System.out.println("------ C Tasklet ------");

            // 返回执行任务完成
            return RepeatStatus.FINISHED;
        };
    }


    @Bean
    public Step stepA() {
        // 如果是通过延时加载去获取参数 那么这里的入参就置为null
        return stepBuilderFactory.get("stepA")
                .tasklet(taskletA())
                .build();
    }


    @Bean
    public Step stepB1() {
        // 如果是通过延时加载去获取参数 那么这里的入参就置为null
        return stepBuilderFactory.get("stepB1")
                .tasklet(taskletB1())
                .build();
    }


    @Bean
    public Step stepB2() {
        // 如果是通过延时加载去获取参数 那么这里的入参就置为null
        return stepBuilderFactory.get("stepB2")
                .tasklet(taskletB2())
                .build();
    }

    @Bean
    public Step stepB3() {
        // 如果是通过延时加载去获取参数 那么这里的入参就置为null
        return stepBuilderFactory.get("stepB3")
                .tasklet(taskletB3())
                .build();
    }

    @Bean
    public Step stepC() {
        // 如果是通过延时加载去获取参数 那么这里的入参就置为null
        return stepBuilderFactory.get("stepC")
                .tasklet(taskletC())
                .build();
    }

    /**
     * 通过流式编程 让一个Flow可以包含多个step
     * @return
     */
    @Bean
    public Flow flowB(){
        return new FlowBuilder<Flow>("flowB")
                .start(stepB1())
                .next(stepB2())
                .next(stepB3())
                .build();
    }

    @Bean
    public Step stepB(){
        return stepBuilderFactory.get("stepB").flow(flowB()).build();
    }





    @Bean
    public Job job() {
        return jobBuilderFactory
                .get("application-step-flow")
                .start(stepA())
                .next(stepB()) // 自定义决策器
                .next(stepC()) // 自定义决策器
                .incrementer(new RunIdIncrementer())    // 使用增量器(run.id自增)
                .build();
    }



    public static void main(String[] args) {
        SpringApplication.run(SpringBatchApplication9.class, args);
    }

}
